﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using Ini;
using System.Xml.Linq;
using System.Xml;



namespace Sequence
{
    public partial class Results : Form
    {
        IniFile oIni = new IniFile("C:\\Sapiens\\Sequence\\Sequence.ini");
        string m_sOut, m_sIn;
        public Results()
        {
            InitializeComponent();

            SetPos();
        }
       
        public Results(string sId,string sProcessId)
        {
            InitializeComponent();
            rtbResults.Text = "";

            string sFilename1 = oIni.IniReadValue("Settings", "TempFolder", "C:\\Sapiens\\Sequence\\Temp\\") + "" + oIni.IniReadValue("Settings", "RunNum", "0") + "-" + sProcessId + "-" + sId + "-In.xml";
            string sFilename2 = oIni.IniReadValue("Settings", "TempFolder", "C:\\Sapiens\\Sequence\\Temp\\") + "" + oIni.IniReadValue("Settings", "RunNum", "0") + "-" + sProcessId + "-" + sId + "-Out.xml";
            this.Text = sFilename1;
            try
            {
                wbResultsIn.Navigate(sFilename1);
                webBrowserOut.Navigate(sFilename2);
                using (StreamReader Outfile = new StreamReader(sFilename2))
                {
                    m_sOut = Outfile.ReadToEnd();
                    BuildXPath(m_sOut);
                }
                using (StreamReader Infile = new StreamReader(sFilename1))
                {
                    m_sIn = Infile.ReadToEnd();
                }
            }
            catch
            {
            }
            SetPos();
        }

        public Results( string sErr, string sInXml, string sOutXml)
        {
            InitializeComponent();            
            try
            {
                sInXml = sInXml.Replace("<?xml version=\"1.0\" encoding=\"UTF8\"?>", "");
                
                using (StreamWriter outfile = new StreamWriter("C:\\Sapiens\\Sequence\\temp.xml", false))
                    outfile.Write(sInXml);

                using (StreamWriter outfile2 = new StreamWriter("C:\\Sapiens\\Sequence\\temp2.xml", false))
                    outfile2.Write(sOutXml);

                BuildXPath(sOutXml);

                wbResultsIn.Navigate("C:\\Sapiens\\Sequence\\temp.xml");
                webBrowserOut.Navigate("C:\\Sapiens\\Sequence\\temp2.xml");
            }
            catch
            {
                rtbResults.Text += "Failed to load XML";
            }

            SetPos();
        }

        private void SetPos()
        {
            this.Left = Convert.ToInt16(oIni.IniReadValue("FrmResults", "Left", "100"));
            this.Width = Convert.ToInt16(oIni.IniReadValue("FrmResults", "Width", "1200"));
            this.Top = Convert.ToInt16(oIni.IniReadValue("FrmResults", "Top", "100"));
            this.Height = Convert.ToInt16(oIni.IniReadValue("FrmResults", "Height", "400"));
        }

        private void BuildXPath(string sOutXml)
        {
            try
            {
                if (sOutXml.Length > 0)
                {
                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(sOutXml);
                    string sPath = "";
                    WalkNode(doc.SelectSingleNode("Root"), ref sPath);
                }
            }
            catch (Exception e) { }
        }


        private void WalkNode(XmlNode oNode, ref string  sPath) 
        {
            string sSavePath = sPath;
            if (sPath == "") 
                sPath += oNode.Name;
            else
                sPath += "/" + oNode.Name;

            foreach (XmlNode oChildNode in oNode.ChildNodes)
            {
                WalkNode(oChildNode,ref sPath);
            }
            if (oNode.HasChildNodes == false)
                rtbXpath.Text += sPath.Replace("/#text","/text()" + "\r\n"); 

            XmlNode oSibling =  oNode.NextSibling;
            while ( oSibling != null)
            {
                oSibling =  oSibling.NextSibling;
            }
            sPath = sSavePath;
        }


        private  string FindXPath(XmlNode node)
        {
            StringBuilder builder = new StringBuilder();
            
            while (node != null)
            {
                switch (node.NodeType)
                {
                    case XmlNodeType.Attribute:
                        builder.Insert(0, "/@" + node.Name);
                        node = ((XmlAttribute) node).OwnerElement;
                        break;
                    case XmlNodeType.Element:
                        int index = FindElementIndex((XmlElement) node);
                        builder.Insert(0, "/" + node.Name + "[" + index + "]");
                        node = node.ParentNode;
                        break;
                    case XmlNodeType.Document:
                        node = null;
                        break;                    
                }
            }
            return builder.ToString();
        }

        private int FindElementIndex(XmlElement element)
        {
             
            XmlNode parentNode = element.ParentNode;
            if (parentNode is XmlDocument)
            {
                return 1;
            }
            XmlElement parent = (XmlElement)parentNode;
            int index = 1;
            foreach (XmlNode candidate in parent.ChildNodes)
            {
                if (candidate is XmlElement && candidate.Name == element.Name)
                {
                    if (candidate == element)
                    {
                        return index;
                    }
                    index++;
                }
            }
            return 0;
        }

        private void Results_Load(object sender, EventArgs e)
        {

        }

        private void Results_FormClosing(object sender, FormClosingEventArgs e)
        {
            oIni.IniWriteValue("FrmResults", "Left", this.Left.ToString());
            oIni.IniWriteValue("FrmResults", "Width", this.Width.ToString());
            oIni.IniWriteValue("FrmResults", "Top", this.Top.ToString());
            oIni.IniWriteValue("FrmResults", "Height", this.Height.ToString());
        }

        private void tabControl1_TabIndexChanged(object sender, EventArgs e)
        {
        
        }

        private void wbResultsIn_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {

        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            try
            {
                XmlDocument oXmlDoc = new XmlDocument();
                oXmlDoc.LoadXml(m_sOut);
                richTextBox2.Text = oXmlDoc.SelectSingleNode(richTextBox1.Text).Value;
                rtbResults.Text = "";

            }
            catch (Exception Ex)
            {
                rtbResults.Text = Ex.Message;
                richTextBox2.Text = "";
            }
        }
    }
}
